using Microsoft.Extensions.Logging;
using SeataNet.Core.Saga;
using SeataNet.Core.TCC;
using SeataNet.Core.Transaction;

namespace SeataNet.Samples
{
    public class SampleOrderService
    {
        private readonly PaymentService _paymentService;
        private readonly InventoryService _inventoryService;
        private readonly ITransactionManager _transactionManager;
        private readonly ILogger<SampleOrderService> _logger;

        public SampleOrderService(
            PaymentService paymentService,
            InventoryService inventoryService,
            ITransactionManager transactionManager,
            ILogger<SampleOrderService> logger)
        {
            _paymentService = paymentService;
            _inventoryService = inventoryService;
            _transactionManager = transactionManager;
            _logger = logger;
        }

        /// <summary>
        /// AT模式创建订单
        /// </summary>
        [GlobalTransactional(Name = "order-create-at", Timeout = 60000)]
        public async Task<string> CreateOrderAsync(string userId, string productId, int quantity)
        {
            _logger.LogInformation($"开始创建订单，用户ID: {userId}, 产品ID: {productId}, 数量: {quantity}");
            
            // 1. 检查库存
            var hasStock = await _inventoryService.CheckStockAsync(productId, quantity);
            if (!hasStock)
            {
                throw new InvalidOperationException("库存不足");
            }

            // 2. 扣减库存
            await _inventoryService.DeductStockAsync(productId, quantity);

            // 3. 创建订单
            var orderId = Guid.NewGuid().ToString("N");
            await SaveOrderAsync(orderId, userId, productId, quantity);

            // 4. 处理支付
            await _paymentService.ProcessPaymentAsync(orderId, userId, quantity * 100m);

            _logger.LogInformation($"订单创建成功，订单ID: {orderId}");
            return orderId;
        }

        /// <summary>
        /// TCC模式创建订单
        /// </summary>
        [GlobalTransactional(Name = "order-create-tcc", Timeout = 60000)]
        public async Task<string> CreateOrderWithTccAsync(string userId, string productId, int quantity)
        {
            _logger.LogInformation($"开始TCC模式创建订单，用户ID: {userId}, 产品ID: {productId}, 数量: {quantity}");
            
            // 1. TCC模式扣减库存
            var stockReserved = await _inventoryService.TryDeductStockAsync(productId, quantity);
            if (!stockReserved)
            {
                throw new InvalidOperationException("库存不足或预留失败");
            }

            // 2. TCC模式创建订单
            var orderId = Guid.NewGuid().ToString("N");
            var orderReserved = await TrySaveOrderAsync(orderId, userId, productId, quantity);
            if (!orderReserved)
            {
                throw new InvalidOperationException("订单预留失败");
            }

            // 3. TCC模式处理支付
            var paymentReserved = await _paymentService.TryProcessPaymentAsync(orderId, userId, quantity * 100m);
            if (!paymentReserved)
            {
                throw new InvalidOperationException("支付预留失败");
            }

            _logger.LogInformation($"TCC模式订单创建成功，订单ID: {orderId}");
            return orderId;
        }

        /// <summary>
        /// Saga模式创建订单
        /// </summary>
        [GlobalTransactional(Name = "order-create-saga", Timeout = 120000)]
        public async Task<string> ProcessOrderWithSagaAsync(string userId, string productId, int quantity)
        {
            _logger.LogInformation($"开始Saga模式处理订单，用户ID: {userId}, 产品ID: {productId}, 数量: {quantity}");
            
            // 1. 创建订单
            var orderId = Guid.NewGuid().ToString("N");
            await SaveOrderAsync(orderId, userId, productId, quantity);

            // 2. 扣减库存
            await _inventoryService.DeductStockAsync(productId, quantity);

            // 3. 处理支付
            await _paymentService.ProcessPaymentAsync(orderId, userId, quantity * 100m);

            _logger.LogInformation($"Saga模式订单处理成功，订单ID: {orderId}");
            return orderId;
        }

        /// <summary>
        /// XA模式创建订单
        /// </summary>
        [GlobalTransactional(Name = "order-create-xa", Timeout = 60000)]
        public async Task<string> CreateOrderWithXaAsync(string userId, string productId, int quantity)
        {
            _logger.LogInformation($"开始XA模式创建订单，用户ID: {userId}, 产品ID: {productId}, 数量: {quantity}");
            
            // 1. 检查库存
            var hasStock = await _inventoryService.CheckStockAsync(productId, quantity);
            if (!hasStock)
            {
                throw new InvalidOperationException("库存不足");
            }

            // 2. 扣减库存
            await _inventoryService.DeductStockXaAsync(productId, quantity);

            // 3. 创建订单
            var orderId = Guid.NewGuid().ToString("N");
            await SaveOrderXaAsync(orderId, userId, productId, quantity);

            // 4. 处理支付
            await _paymentService.ProcessPaymentXaAsync(orderId, userId, quantity * 100m);

            _logger.LogInformation($"XA模式订单创建成功，订单ID: {orderId}");
            return orderId;
        }

        private async Task SaveOrderAsync(string orderId, string userId, string productId, int quantity)
        {
            // 模拟保存订单到数据库
            _logger.LogInformation($"保存订单: {orderId}");
            await Task.Delay(50); // 模拟数据库操作
        }

        private async Task<bool> TrySaveOrderAsync(string orderId, string userId, string productId, int quantity)
        {
            // 模拟TCC模式的Try阶段
            _logger.LogInformation($"TCC Try: 预留订单: {orderId}");
            await Task.Delay(50); // 模拟数据库操作
            return true; // 假设总是成功
        }

        private async Task SaveOrderXaAsync(string orderId, string userId, string productId, int quantity)
        {
            // 模拟XA模式保存订单
            _logger.LogInformation($"XA保存订单: {orderId}");
            await Task.Delay(50); // 模拟数据库操作
        }

        // TCC模式的Confirm方法
        [GlobalTransactionalConfirm]
        public async Task ConfirmSaveOrderAsync(string orderId)
        {
            _logger.LogInformation($"TCC Confirm: 确认订单: {orderId}");
            await Task.Delay(20); // 模拟数据库操作
        }

        // TCC模式的Cancel方法
        [GlobalTransactionalCancel]
        public async Task CancelSaveOrderAsync(string orderId)
        {
            _logger.LogInformation($"TCC Cancel: 取消订单: {orderId}");
            await Task.Delay(20); // 模拟数据库操作
        }

        // Saga模式的补偿方法
        [GlobalTransactionalCompensation]
        public async Task CompensateSaveOrderAsync(string orderId)
        {
            _logger.LogInformation($"Saga Compensate: 补偿订单: {orderId}");
            await Task.Delay(20); // 模拟数据库操作
        }
    }
}